#include<iostream>
using namespace std;
/*
#include<string>
typedef typename string::size_type mtype;
我们使用typename来告诉编译器size_type是一个
类型？

但是在模板中，类型可能是未知的。我们不能假定用
::访问的一定就是一个类型。此时需要额外的信息来
传递给模板
*/


/*
 *需要注意的是，类模板并不是类型。加上实例化的
 *传入类型才是完整的类型。
 */

/*
template<typename T,typename U>
class test{
	private:
		int a;
	public:
		
		test(int na);
		template<typename N> void print(N& useu);
};

template<typename T,typename U>
test<T,U>::test(int na){
	a=na;
}

template<typename T,typename U>
template<typename N>
void test<T,U>::print(N& useu){
	useu<<a<<endl;
}
模板函数也要传递类型参数
构造函数也是可以传递模板
顺便说一句：函数也是用的时候才
实例化。
*/

/*
 *模板的友元
 *一个模板的非模板友元是所有模板实例的友元
 *如果友元是模板，那么就存在一个授权的问题
 
template<typename datatype,typename outtype> class test;
template<typename datatype,typename outtype> void print(outtype& uset,test<datatype,outtype>);

template<typename datatype,typename outtype=ostream>
class test{
	friend void print<datatype,outtype>(outtype& uset,test<datatype,outtype>);
	private:
		datatype a;
	public:
		test(datatype na):a(na){}
		
};

template<typename datatype,typename outtype>
void print(outtype& uset,test<datatype,outtype> nt){
	uset<<nt.a<<endl;
}
*/

/*
为一个类模板声明接受特定类型类实例的友元函数
template<typename datatype>
class test{
	template<typename outtype> friend void print(outtype& out,test<int> nt);
	private:
		datatype data;
	public:
		test(datatype na);
			
};

template<typename datatype>
test<datatype>::test(datatype na):data(na){}

template<typename outtype>
void print(outtype& out,test<int> nd){
	out<<nd.data<<endl;
}
*/

/*
 * 一个类模板的友元模板。友元模板被授权访问类模版的
 * 实例是指与类模版相同实例化的实例。如果不是这样的
 * 授权特定实例化的友元模板可以直接在类内声明。
template<typename totake> class fri;

template<typename datatype>
class test{
	friend class fri<test<datatype>>; 
	private:
		datatype data;
	public:
		test(datatype nd):data(nd){}
};

template<typename totake>
class fri{
	public:
		void to_take(totake nt);
		
};
template<typename totake>
void fri<totake>::to_take(totake nt){
	cout<<nt.data<<endl;
}
*/
int main(){
	/*111
	test<int,char>a(3);
	a.print(cout);
	
	test<int> a(3);
	print(cout,a);
	*/

	/*
	int i=2;
	test<int> a(i);
	print(cout,a);
	*/

	/*
	test<int> a(2);
	fri<test<int>> b;
	b.to_take(a);
	*/
}
